package com.aiti.lulian.gxmh.service.impl;

import cn.hutool.core.util.StrUtil;
import com.aiti.base.core.base.service.iml.BaseSerivceImpl;
import com.aiti.base.core.utils.message.Message;
import com.aiti.lulian.feign.CloudShowManagerSubService;
import com.aiti.lulian.gxmh.dto.GxmhMessageDto;
import com.aiti.lulian.gxmh.entity.GxmhMessage;
import com.aiti.lulian.gxmh.entity.GxmhMessageUser;
import com.aiti.lulian.gxmh.service.IGxmhMessageService;
import com.aiti.lulian.mapper.LuLianEnterpriseMapper;
import com.aiti.lulian.mapper.gxmh.GxmhMessageMapper;
import com.aiti.lulian.mapper.gxmh.GxmhMessageUserMapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GxmhMessageServiceImpl extends BaseSerivceImpl<GxmhMessageMapper, GxmhMessage> implements IGxmhMessageService {

    @Autowired
    private GxmhMessageMapper gxmhMessageMapper;

    @Autowired
    private GxmhMessageUserMapper gxmhMessageUserMapper;

    @Autowired
    private LuLianEnterpriseMapper luLianEnterpriseMapper;

    @Autowired
    private CloudShowManagerSubService cloudShowManagerSubService;

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Message add(GxmhMessageDto dto) {
        GxmhMessage gxmhMessage = new GxmhMessage();
        BeanUtils.copyProperties(dto, gxmhMessage);
        Integer count = gxmhMessageMapper.selectCount(null);
        String baseId = "MSG_" + String.format("%03d", count == 0 ? 1 : ++count);
        gxmhMessage.setBaseId(baseId);
        gxmhMessage.setBaseCreateTime(new Date());
        gxmhMessageMapper.insert(gxmhMessage);

        // 根据消息接收对象进行批量记录
        List<String> userIds;
        List<GxmhMessageUser> gxmhMessageUsers = new ArrayList<>();
        if (StrUtil.isNotBlank(dto.getReceiver())) {
            if (StrUtil.equals(dto.getReceiver(), "1")) {
                // 全体用户
                userIds = cloudShowManagerSubService.getAllUsers();
            } else if (StrUtil.equals(dto.getReceiver(), "2") || StrUtil.equals(dto.getReceiver(), "3")) {
                // 企业用户 或 政府用户
                userIds = luLianEnterpriseMapper.selectUsers(dto.getReceiver());
            } else {
                return Message.fail("请正确选择消息接收权限");
            }
        } else {
            return Message.fail("请选择消息接收权限");
        }
        if (!userIds.isEmpty()) {
            gxmhMessageUsers = userIds.stream().map(i -> {
                GxmhMessageUser gxmhMessageUser = new GxmhMessageUser();
                gxmhMessageUser.setMessageId(gxmhMessage.getBaseId());
                gxmhMessageUser.setUserId(i);
                return gxmhMessageUser;
            }).collect(Collectors.toList());
        }
        if (!gxmhMessageUsers.isEmpty()) {
//            gxmhMessageUserService.saveBatch(gxmhMessageUsers); // 太慢
            batchInsert(gxmhMessageUsers);
        }
        return Message.success("推送成功");
    }

    /**
     * 分批插入，性能提升了10倍
     */
    public void batchInsert(List<GxmhMessageUser> dataList) {
        int batchSize = 5000;
        for (int i = 0; i < dataList.size(); i += batchSize) {
            List<GxmhMessageUser> subList = dataList.subList(i, Math.min(i + batchSize, dataList.size()));
            gxmhMessageUserMapper.insertBatch(subList);
        }
    }

    @Override
    public List<GxmhMessage> getList(Page<GxmhMessage> page, GxmhMessageDto dto) {
        return gxmhMessageMapper.selectMessageList(page, dto);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Message delete(GxmhMessageDto dto) {
//        gxmhMessageUserService.remove(new LambdaQueryWrapper<GxmhMessageUser>().eq(GxmhMessageUser::getMessageId, dto.getBaseId()));
//        gxmhMessageMapper.deleteById(dto.getBaseId());
        this.update(new LambdaUpdateWrapper<GxmhMessage>().eq(GxmhMessage::getBaseId, dto.getBaseId()).set(GxmhMessage::getIsDelete, 1));
        return Message.success("删除成功");
    }
}
